/** Fichier définissant la composition de formes.
 *
 * Ce fichier contient la définition de la classe FormeComposee.
 *
 * @file FormeComposee.hpp
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 * @date 23 Avril 2004
 */
#ifndef _FORME_COMPOSEE_H
#define _FORME_COMPOSEE_H

#include "Forme.hpp"

#include "boost/shared_ptr.hpp"

/** Définit les opérations de composition disponibles.
 *
 * Les diverses opérations de composition de deux formes sont les
 * différentes valeurs de ce type énuméré.
 */
enum operateur
{
    inter,     /**< Intersection mathématique des formes. */
    unions,    /**< Union  mathématique des formes. */
    difference /**< Différence asymétrique des formes. */
};

/** Classe qui implémente la composition de Formes. 
 *
 * On peut faire une union, intersection (les deux au sens
 * mathématique) ou une différence (ce qui représente l'ensemble de la
 * première forme moins tout ce qui apparentient à l'autre).
 *
 * Forme::PseudoCentre est défini comme le centre de la sphère qui
 * inclu les sphères des deux instances à composer.
 *
 * @todo Mieux calculer le PseudoRayon et la positon de PseudoCentre :
 * plus la sphère "circonscrite" est petite et plus le temps de calcul
 * diminue.
 *
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 * @date 23 Avril 2004
 *
 * @class FormeComposee "FormeComposee.hpp" "Formes/FormeComposee.hpp"
 */
class FormeComposee : public Forme
{
protected:
    /**
   * Tableau statique contenant les deux formes que l'on a décidé
   * d'assembler.
   */
    const Forme *form[2];
    /**
   * Opération de composition choisie.
   */
    operateur op;
public:
    typedef boost::shared_ptr< FormeComposee > SharedPtr;
    FormeComposee();
    FormeComposee(const operateur& ,const Forme *,const Forme *);
    virtual ~FormeComposee();
    Coord trouveIntersection(Rayon const &) const;
    VecteurU normale(Coord const &) const;
    bool estDans(Coord const &) const;
    bool estSur(Coord const &) const;
    void mapping(const Coord &, int &i, int &j, const int &frequence, const int &Hauteur, const int &Largeur) const;
    std::ostream& affiche(std::ostream& os) const;
    Coord intrinseque(const Coord& pt) const;
};

#endif
